package com.fastloan.safe.mgt.user.service.impl;

import com.fastloan.safe.core.param.RoleTypeEnum;
import com.fastloan.safe.core.util.ManagerKit;
import com.fastloan.safe.mgt.auth.model.CmuUserFun;
import com.fastloan.safe.mgt.auth.model.CmuUserRole;
import com.fastloan.safe.mgt.auth.service.CmuUserFunService;
import com.fastloan.safe.mgt.auth.service.CmuUserRoleService;
import com.fastloan.safe.mgt.org.model.CmuOrgUser;
import com.fastloan.safe.mgt.org.service.CmuOrgUserService;
import com.fastloan.safe.mgt.root.model.CmDefFun;
import com.fastloan.safe.mgt.root.model.vo.DefFunTreeVo;
import com.fastloan.safe.mgt.root.service.CmDefFunService;
import com.fastloan.safe.mgt.root.service.CmFunService;
import com.fastloan.safe.mgt.user.dao.CmuUserMapper;
import com.fastloan.safe.mgt.user.model.CmuUser;
import com.fastloan.safe.mgt.user.model.vo.CmuUserVo;
import com.fastloan.safe.mgt.user.service.CmuUserService;
import com.kawins.base.BaseMapper;
import com.kawins.base.baseabs.BaseServiceImpl;
import com.kawins.result.ResultEnum;
import com.kawins.result.ResultTo;
import com.kawins.shiro.temp.util.PasswordUtil;
import com.kawins.shiro.temp.util.ShiroKit;
import com.kawins.supers.file.IFileManager;
import com.kawins.supers.file.core.FileLoadBean;
import com.kawins.supers.table.manager.DataTable;
import com.kawins.supers.tree.Bean2TreeUtil;
import com.kawins.util.colle.ListSortUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;

/**
 * @author rankai
 *         createTime 2017-09-2017/9/25 17:01
 */
public class CmuUserServiceImpl extends BaseServiceImpl<CmuUser> implements CmuUserService {

    @Autowired
    private CmuUserMapper userMapper;

    @Autowired
    private CmuUserRoleService userRoleService;

    @Autowired
    private CmDefFunService defFunService;

    @Autowired
    private CmFunService funService;

    @Autowired
    private CmuUserFunService userFunService;

    @Autowired
    private CmuOrgUserService orgUserService;

    @Autowired
    private IFileManager fileService;

    @Override
    protected BaseMapper<CmuUser> buildDao() {
        return userMapper;
    }

    @Override
    @DataTable(name = "cmuUserPageList")
    public List<CmuUserVo> pageList(Map<String, Object> map) {
        return userMapper.pageList(map);
    }

    @Override
    @DataTable(name = "cmuUserPageListByOrgId")
    public List<CmuUserVo> pageListByOrgId(Map<String, Object> map) {
        Object orgId = map.get("orgId");
        if (orgId == null) {
            map.put("orgId", ManagerKit.getOrgId());
        }
        return userMapper.pageListByOrgId(map);
    }


    @Override
    public void insertWithRole(CmuUser user, String[] roleIds, String orgId, boolean isAdmin, MultipartFile... files) {
        log.debug("新增用户:{},roleIds长度:{}", user, roleIds.length);

        if (files[0] != null && files[0].getSize() > 0) {
            user.setUserProfile(uploadFile(files[0]));
        }
        if (files[1] != null && files[1].getSize() > 0) {
            user.setIdentityFront(uploadFile(files[1]));
        }
        if (files[2] != null && files[2].getSize() > 0) {
            user.setIdentitySide(uploadFile(files[2]));
        }
        user.setCreateBy(ManagerKit.getUserId());
        user.setCreateTime(new Date());
        String uuid = UUID.randomUUID().toString();
        user.setSalt(uuid);
        user.setPassword(PasswordUtil.encryptPassword(CmuUserService.DEF_PASSWORD, uuid));
        if (isAdmin) {
            user.setIdCard(null);
            user.setRootRoleId(roleIds[0]);
            insertSelective(user);
        } else {
            user.setRootRoleId(null);
            insertSelective(user);
            orgUserService.insertSelective(new CmuOrgUser().setOrgId(orgId).setUserId(user.getId()));
            bachInsert(user, roleIds);
        }
    }

    private String uploadFile(MultipartFile file) {
        if (file != null && file.getSize() > 0) {
            FileLoadBean loadBean = fileService.upload(file);
            return loadBean.getFileId().toString();
        }
        return null;
    }


    @Override
    public void updateWithRole(CmuUser user, String[] roleIds, MultipartFile logoFile, boolean isAdmin) {
        if (logoFile != null && logoFile.getSize() > 0) {
            CmuUser cmuUser = selectByPrimaryKey(user.getId());
            String userProfile = cmuUser.getUserProfile();
            FileLoadBean loadBean;
            if (StringUtils.isNotBlank(userProfile)) {
                loadBean = fileService.update(cmuUser.getUserProfile(), logoFile);
            } else {
                loadBean = fileService.upload(logoFile);
            }
            user.setUserProfile(loadBean.getFileId().toString());
        }
        user.setSalt(null);
        user.setPassword(null);
        user.setCreateBy(null);
        user.setCreateTime(null);
        user.setUsername(null);
        user.setStatus(null);
        if (isAdmin) {
            user.setIdCard(null);
            user.setRootRoleId(roleIds[0]);
            updateByPrimaryKeySelective(user);
        } else {
            user.setRootRoleId(null);
            updateByPrimaryKeySelective(user);
            userRoleService.delete(new CmuUserRole().setUserId(user.getId()));
            bachInsert(user, roleIds);

        }
    }

    @Override
    public ResultTo updatePwd(String oldPwd, String newPwd) {
        CmuUser cmuUser = selectByPrimaryKey(ManagerKit.getUserId());
        String encryptPassword = PasswordUtil.encryptPassword(oldPwd, cmuUser.getSalt());
        if (cmuUser.getPassword().equals(encryptPassword)) {
            cmuUser.setPassword(encryptPassword);
            updateByPrimaryKeySelective(cmuUser);
            return new ResultTo();
        }
        return new ResultTo(ResultEnum.OPERATION_FAILED, "旧密码错误");
    }

    @Override
    public ResultTo update(Integer updateType, CmuUser user) {
        //TODO 此处需要增加权限判断
        CmuUser cmuUser = selectByPrimaryKey(user.getId());
//        if (StringUtils.isBlank(user.getRootRoleId())) {
//            if (!ShiroKit.hasPermission("")) {
//                return new ResultTo(ResultEnum.OPERATION_FAILED);
//            }
//        } else {
//            if (!ShiroKit.hasPermission("")) {
//                return new ResultTo(ResultEnum.OPERATION_FAILED);
//            }
//        }
        switch (updateType) {
            case 1: { //重置密码
                cmuUser.setPassword(PasswordUtil.encryptPassword(DEF_PASSWORD, cmuUser.getSalt()));
                updateByPrimaryKeySelective(cmuUser);
                break;
            }
            case 2: { //锁定解锁
                Integer status = cmuUser.getStatus();
                if (status.equals(0)) {
                    cmuUser.setStatus(1);
                } else {
                    cmuUser.setStatus(0);
                }
                updateByPrimaryKeySelective(cmuUser);
                break;
            }
            default: {
                return new ResultTo(ResultEnum.PARAM_ERROR, "未知操作");
            }
        }
        return new ResultTo();
    }

    @Override
    public List<DefFunTreeVo> paramUserFun(String userId) {
        List<DefFunTreeVo> defFunTreeVos = funService.selectFunByOrg();
        List<CmDefFun> cmDefFuns = defFunService.selectByUserId(userId);
        for (DefFunTreeVo defFunTreeVo : defFunTreeVos) {
            for (CmDefFun cmDefFun : cmDefFuns) {
                if (cmDefFun.getId().equals(defFunTreeVo.getId())) {
                    defFunTreeVo.setCheck(true);
                }
            }
        }
        return buildDefFunTree(defFunTreeVos);
    }

    @Override
    public void updateUserFun(String userId, String[] funIds) {
        List<DefFunTreeVo> defFunTreeVos = funService.selectFunByOrg();
        HashSet<String> oldFunSet = new HashSet<>(defFunTreeVos.size());
        for (DefFunTreeVo defFunTreeVo : defFunTreeVos) {
            oldFunSet.add(defFunTreeVo.getId());
        }
        HashSet<String> newFunSet = new HashSet<>(funIds.length);
        for (String funId : funIds) {
            newFunSet.add(funId);
        }
        HashSet<String> cloneOldFunSet = new HashSet<>(oldFunSet);
        oldFunSet.removeAll(newFunSet);
        newFunSet.removeAll(cloneOldFunSet);
        if (oldFunSet.size() > 0 || newFunSet.size() > 0) {
            List<CmuUserFun> list = new ArrayList<>(oldFunSet.size());
            for (String funId : oldFunSet) { //去掉的
                list.add(new CmuUserFun().setUserId(userId).setDefFunId(funId).setIsAdd(0));
            }
            for (String funId : newFunSet) { //增加的
                list.add(new CmuUserFun().setUserId(userId).setDefFunId(funId).setIsAdd(1));
            }
            userFunService.insertList(list);
        }
        clearAuth(userId);
    }


    @Override
    public List<CmuUserVo> selectUserByOrgId(String orgId, boolean hasSon) {
        if (StringUtils.isBlank(orgId)) {
            orgId = ManagerKit.getTopOrgId();
        }
        return userMapper.selectUserByOrgId(orgId, hasSon);
    }

    @Override
    public List<CmuUserVo> selectUserByRoleType(RoleTypeEnum roleType, String userOrgId) {
        return userMapper.selectUserByRoleType(ManagerKit.getTopOrgId(), roleType.getCode(), userOrgId);
    }

    @Override
    public List<CmuUser> selectByRoleId(String roleId, String userOrgId) {
        return userMapper.selectByRoleId(roleId, userOrgId);
    }

    @Override
    public List<CmuUser> selectBySonAdminNoHasOrg() {
        return userMapper.selectBySonAdminNoHasOrg(ManagerKit.getTopOrgId());
    }

    @Override
    public boolean changePwd(String userId, String oldPwd, String newPwd) {
        CmuUser cmuUser = selectByPrimaryKey(userId);
        if (cmuUser.getPassword().equals(PasswordUtil.encryptPassword(oldPwd, cmuUser.getSalt()))) {
            String string = UUID.randomUUID().toString();
            String password = PasswordUtil.encryptPassword(newPwd, string);
            cmuUser = new CmuUser();
            cmuUser.setId(userId);
            cmuUser.setPassword(password);
            cmuUser.setSalt(string);
            updateByPrimaryKeySelective(cmuUser);
            return true;
        }
        return false;
    }

    @Override
    public boolean uploadIdentity(String userId, MultipartFile identityFront, MultipartFile identitySide) {
        CmuUser cmuUser = userMapper.selectByPrimaryKey(userId);
        if (StringUtils.isBlank(cmuUser.getIdentityFront())) {
            fileService.delete(cmuUser.getIdentityFront());
            cmuUser.setIdentityFront(uploadFile(identityFront));
        }
        if (StringUtils.isBlank(cmuUser.getIdentitySide())) {
            fileService.delete(cmuUser.getIdentitySide());
            cmuUser.setIdentityFront(uploadFile(identitySide));

        }
        updateByPrimaryKeySelective(cmuUser);
        return true;
    }

    private void bachInsert(CmuUser user, String[] roleIds) {
        List<CmuUserRole> list = new ArrayList<>(roleIds.length);
        for (int i = 0; i < roleIds.length; i++) {
            if (i == 0) {
                list.add(new CmuUserRole().setRoleId(roleIds[i]).setUserId(user.getId()).setIsDef(1));
                continue;
            }
            list.add(new CmuUserRole().setRoleId(roleIds[i]).setUserId(user.getId()).setIsDef(0));
        }
        userRoleService.insertList(list);
    }

    private List<DefFunTreeVo> buildDefFunTree(List<DefFunTreeVo> defFunTreeVos) {
        LinkedHashMap<String, Integer> orderMap = new LinkedHashMap<>();
        orderMap.put("shorts", ListSortUtil.ASC);
        Bean2TreeUtil<DefFunTreeVo> bean2TreeUtil = new Bean2TreeUtil<>(orderMap);
        return bean2TreeUtil.getChildNodesByParentId(defFunTreeVos, CmDefFunService.TOP_FUN_PARENT_ID);
    }

    private void clearAuth(String userId) {
        CmuUser cmuUser = selectByPrimaryKey(userId);
        ShiroKit.clearAuthorizationInfo(cmuUser.getUsername());
    }
}
